using RealtimeCollabGame.Application.Commands;
using RealtimeCollabGame.Application.Interfaces;
using RealtimeCollabGame.Domain.Entities;

namespace RealtimeCollabGame.Application.Handlers;

public class JoinGameCommandHandler
{
    private readonly IGameRepository _gameRepository;
    private readonly IPlayerRepository _playerRepository;

    public JoinGameCommandHandler(IGameRepository gameRepository, IPlayerRepository playerRepository)
    {
        _gameRepository = gameRepository;
        _playerRepository = playerRepository;
    }

    public async Task<Game> HandleAsync(JoinGameCommand command)
    {
        var game = await _gameRepository.GetByCodeAsync(command.GameCode);
        if (game == null)
        {
            throw new InvalidOperationException($"房间代码 {command.GameCode} 不存在");
        }

        if (game.HasPassword && !game.ValidatePassword(command.Password ?? string.Empty))
        {
            throw new InvalidOperationException("房间密码错误");
        }

        if (game.Status != Domain.Enums.GameStatus.Waiting)
        {
            throw new InvalidOperationException("游戏已开始，无法加入");
        }

        // 检查玩家是否已经在房间中
        var existingPlayerInGame = game.Players.FirstOrDefault(p => p.NickName == command.PlayerNickName);
        if (existingPlayerInGame != null)
        {
            // 玩家已经在房间中，直接返回游戏状态
            return game;
        }

        // 创建或获取玩家
        var player = await _playerRepository.GetByNickNameAsync(command.PlayerNickName);
        if (player == null)
        {
            // 检查是否是第一个玩家（房主）
            bool isHost = game.Players.Count == 0;
            player = new Player(command.PlayerNickName, null, isHost);
            await _playerRepository.AddAsync(player);
        }

        // 如果是第一个玩家且还没有房主，设置为房主
        bool shouldBeHost = game.Players.Count == 0 && game.HostId == null;
        game.AddPlayer(player, shouldBeHost);
        await _gameRepository.UpdateAsync(game);

        return game;
    }
}